﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using Ionic.Zip;

class InputOutput
{
    const int BUFF_SIZE = 8192;

    private void SHA1()
    {
        FileStream sha1 = new FileStream("SHA1.bin", FileMode.Open, FileAccess.Read);
        using (sha1)
        {
            byte[] buffy = new byte[BUFF_SIZE];
            MemoryStream mStream = new MemoryStream();
            int counter = 0;
            while (true)
            {
                int bytesRead = sha1.Read(buffy, 0, BUFF_SIZE);
                if (bytesRead == 0)
                {
                    break;
                }
                counter++;
                mStream.Write(buffy, 0, bytesRead);
            }
            if (counter <= 16)
            {
                SHA1 sh = new SHA1CryptoServiceProvider();
                byte[] result = sh.ComputeHash(mStream.ToArray());
                for (int i = 0; i < result.Length; i++)
                {
                    Console.Write("{0:x}", result[i]);
                }
                Console.WriteLine();
            }
        }
    }

    public class Student
    {
        private string fName;
        private string lName;
        private int fNumber;

        public Student(string fName, string lName, int fNumber)
        {
            FName = fName;
            LName = lName;
            FNumber = fNumber;
        }

        public string FName
        {
            get
            {
                return fName;
            }
            set
            {
                if (value != null && value != "")
                {
                    fName = value;
                }
                else
                {
                    throw new ArgumentException("Invalid First Name");
                }
            }
        }
        public string LName
        {
            get
            {
                return lName;
            }
            set
            {
                if (value != null && value != "")
                {
                    lName = value;
                }
                else
                {
                    throw new ArgumentException("Invalid Last Name");
                }
            }
        }
        public int FNumber
        {
            get
            {
                return fNumber;
            }
            set
            {
                if (value > 0)
                {
                    fNumber = value;
                }
                else
                {
                    throw new ArgumentException("Invalid Faculty Number");
                }
            }
        }
    }

    public static void AddStudent(string fileName, Student st)
    {
        FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write);
        using(fs)
        {
            BinaryWriter writer = new BinaryWriter(fs);
            using (writer)
            {
                writer.Write(st.FName);
                writer.Write(st.LName);
                writer.Write(st.FNumber);
            }
        }
    }
    public static void DeleteStudent(string fileName, int fNumber)
    {
        FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
        using (fs)
        {
            BinaryReader reader = new BinaryReader(fs);
            using (reader)
            {
                BinaryWriter writer = new BinaryWriter(File.Create("tmp.bin"));
                using (writer)
                {
                    while (reader.PeekChar() != -1)
                    {
                        string fName = reader.ReadString();
                        string lName = reader.ReadString();
                        int fNum = reader.ReadInt32();
                        if (fNum != fNumber)
                        {
                            {
                                writer.Write(fName);
                                writer.Write(lName);
                                writer.Write(fNum);
                            }
                        }
                    }
                }
            }
        }
        File.Delete(fileName);
        File.Move("tmp.bin", fileName);
    }
    public static void PrintAllStudents(string fileName)
    {
        FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
        using (fs)
        {
            BinaryReader reader = new BinaryReader(fs);
            using (reader)
            {
                while (reader.PeekChar() != -1)
                {
                    string fName = reader.ReadString();
                    string lName = reader.ReadString();
                    int fNum = reader.ReadInt32();
                    Console.WriteLine("FirstName: {0}\nLastName: {1}\nFacultyNumber: {2}", fName, lName, fNum);
                }
            }
        }
    }

    public void RC4(ref Byte[] bytes, Byte[] key)
    {
        Byte[] s = new Byte[256];
        Byte[] k = new Byte[256];
        Byte temp;
        int i, j;

        for (i = 0; i < 256; i++)
        {
            s[i] = (Byte)i;
            k[i] = key[i % key.GetLength(0)];
        }

        j = 0;
        for (i = 0; i < 256; i++)
        {
            j = (j + s[i] + k[i]) % 256;
            temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }

        i = j = 0;
        for (int x = 0; x < bytes.GetLength(0); x++)
        {
            i = (i + 1) % 256;
            j = (j + s[i]) % 256;
            temp = s[i];
            s[i] = s[j];
            s[j] = temp;
            int t = (s[i] + s[j]) % 256;
            bytes[x] ^= s[t];
        }
    }


    static void Main()
    {
        AddStudent("students.bin", new Student("Pe6o", "Ivanov", 123));
        AddStudent("students.bin", new Student("Go6o", "Petrov", 4566));
        AddStudent("students.bin", new Student("Ivan", "Mihov", 894));
        AddStudent("students.bin", new Student("Mi6o", "Ivanov", 156));
        DeleteStudent("students.bin", 894);
        PrintAllStudents("students.bin");

        //ZipFile zip = new ZipFile();  
        //using (zip)
        //{
        //    zip.AddFile("students.bin");
        //    zip.Save("myzip.zip");
        //    zip.ExtractAll("Students");
        //}

        //RC4 rc = new RC4();
        //String output = rc.Encrypt("keyString", "Sample String");
        //Console.WriteLine(output);
    }
}

